<?php
/**
 * Notes:
 * User: wudg <544038230@qq.com>
 * Date: 2025/9/3 17:17
 */

namespace App\Service\User;


use App\Constants\System\SysStatusConst;
use App\Constants\User\UserCardInfoTypeConst;
use App\Dao\Users\UserCategoryDao;
use App\Dao\Users\UsersAccountDao;
use App\Dao\Users\UsersCardDao;
use App\Dao\Users\UsersCardsInfoDao;
use App\Exception\ServiceException;
use App\Model\Users\User;
use App\Model\Users\UsersCard;
use App\Model\Users\UsersCardsInfo;
use App\Service\System\QrCodeService;
use App\Utils\AmountUtils;
use App\Utils\HelperUtils;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Redis\Redis;
use function Hyperf\Config\config;

class UserCardService
{
    #[Inject]
    protected Redis $redis;

    protected $cacheCardPre ='card:distribute';



    #[Inject]
    protected UsersCardsInfoDao $usersCardsInfoDao;




    #[Inject]
    protected UsersCardDao $usersCardDao;


    #[Inject]
    protected UsersAccountDao $usersAccountDao;

    public function cardList(array $params)
    {
        $userInfo = auth()->user();
        $isSub = UserService::isSubAccount($userInfo);
        $searchUid= $userInfo->getId();
        if($isSub)
        {
            $searchUid = $userInfo->soft_id;
        }
        $queryModel = UsersCard::query()
            ->select(['id','card_name','card_level','card_color','card_discount','card_desc','card_cids'])
            ->where('uid','=',$searchUid)->where('is_del','=',SysStatusConst::NORMAL->value);
        $queryModel->orderBy('id','desc')->limit(100);
        $categoryData = $queryModel->get()->toArray();
        $allCids = $mapCategoryData = [];
        foreach ($categoryData as &$item)
        {
            $item['color_name'] = config('card.theme_color')[$item['card_color']]['name'] ?? '';
            $item['card_cids'] = json_decode($item['card_cids'],true);
            $item['card_discount'] = AmountUtils::yuanTofen($item['card_discount']);
            $allCids = array_merge($allCids,$item['card_cids']);
        }
        if(count($allCids))
        {
            $dbCategoryData = (new UserCategoryDao())->getCateByIds($allCids,['id','name']);
            $mapCategoryData = array_column($dbCategoryData,'name','id');
        }
        unset($item);
        foreach ($categoryData as &$item)
        {
            if(count($item['card_cids']))
            {
                array_map(function($cid)use($mapCategoryData,&$item) {
                    $item['map_name'][] = $mapCategoryData[$cid] ?? '';
                },$item['card_cids']);
            }
        }
        return $categoryData;
    }

    /**
     * 会员卡保存
     * @param array $data
     * @return \Hyperf\Tappable\HigherOrderTapProxy|int|mixed|null
     */
    public function cardSave(array $data)
    {
        $userInfo = auth()->user();
        if(!empty($data['id']))
        {
            $userCategory = UsersCard::query()->where('id','=',$data['id'])->where('uid','=',$userInfo->getId())->first();
        }else{
            $userCategory = new UsersCard();
        }

        if(!empty($data['card_cids'])) $data['card_cids'] = json_encode($data['card_cids'],JSON_UNESCAPED_UNICODE);
        if(!empty($data))
        {
            $data['card_discount'] = AmountUtils::fenToYuan($data['card_discount']);
        }
        $data['uid'] = $userInfo->getId();
        $res = $userCategory->fill($data)->save();
        if(!$res) throw new ServiceException("更新失败");

        return $userCategory->id;
    }

    /**
     * 获取会员卡详细
     * @param int $id
     * @return array
     */
    public function cardInfo(int $id)
    {
        $userCategory = UsersCard::query()->where('id','=',$id)->first();
        if(!$userCategory) throw new ServiceException("会员卡不存在");
        $userCategoryData = $userCategory->toArray();
        $userCategoryData['card_cids'] = json_decode($userCategoryData['card_cids'],true);
        $dbCategoryData = (new UserCategoryDao())->getCateByIds($userCategoryData['card_cids'],['id','name']);
        $mapCategoryData = array_column($dbCategoryData,'name','id');
        array_map(function($cid)use($mapCategoryData,&$userCategoryData) {
            $userCategoryData['map_name'][] = $mapCategoryData[$cid] ?? '';
        },$userCategoryData['card_cids']);
        $cartDistribute = $this->redis->get("{$this->cacheCardPre}:{$userCategory->id}");
        $userCategoryData['company_name'] = '';
        if(!empty($cartDistribute))
        {
            $userCategoryData['company_name'] = json_decode($cartDistribute,true)['company_name'];
        }
        return $userCategoryData;
    }

    /**
     * 生成会员卡领取二维码
     * @param int $id
     * @param int $type
     * @param float $amount
     * @return string
     * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
     */
    public function cardQrcode(int $id,int $type,float $amount)
    {
        $userInfo = auth()->user();
        $userCardInfo = UsersCard::query()->where('id','=',$id)->where('uid','=',$userInfo->getId())->first();
        if(!$userCardInfo) throw new ServiceException("会员卡不存在");

        if($userInfo->company_name == '') throw new ServiceException("请先设置公司名称");

        $this->redis->setex("{$this->cacheCardPre}:{$userCardInfo->id}",86400,json_encode([
            'company_name' => $userInfo->company_name
        ]));
        $app = HelperUtils::miniProgram();
        $scene = 's=card&c='.$userCardInfo->id.'&m='.$amount.'&t='.$type;

        $response = $app->getClient()->postJson('/wxa/getwxacodeunlimit', [
            'scene' => $scene,
            'page' => 'pages/member/index',
            'width' => 430,
            'check_path' => false,
        ]);
        if($response->getStatusCode() != 200) throw new ServiceException("生成二维码失败");
        $responseData = $response->toPsrResponse();
        return "data:image/png;base64,".base64_encode($responseData->getBody()->getContents());
    }


    /**
     * 获取会员领取的会员卡信息
     * @param int $limit
     * @return mixed[]
     */
    public function userCardData(int $limit = 20)
    {
        $userInfo = auth()->user();
        $model = UsersCardsInfo::query()->where('uid','=',$userInfo->getId());

        $allCids = $mapCategoryData = [];
        $userCardData = $model->where('status','=',SysStatusConst::NORMAL->value)
            ->limit($limit)->get()->toArray();

        foreach ($userCardData as &$item)
        {
            $item['card_cids'] = json_decode($item['card_cids'],true);
            $item['card_discount'] = AmountUtils::yuanTofen($item['card_discount']);
            $item['amount'] = AmountUtils::fenToYuan($item['amount']);
            $allCids = array_merge($allCids,$item['card_cids']);
        }

        if(count($allCids))
        {
            $dbCategoryData = (new UserCategoryDao())->getCateByIds($allCids,['id','name']);
            $mapCategoryData = array_column($dbCategoryData,'name','id');
        }
        unset($item);
        foreach ($userCardData as &$item)
        {
            if(count($item['card_cids']))
            {
                array_map(function($cid)use($mapCategoryData,&$item) {
                    $item['cate_name'][] = $mapCategoryData[$cid] ?? '';
                },$item['card_cids']);
            }
        }
        return $userCardData;
    }

    /**
     * 领取会员卡
     * @param array $params
     * @return array
     */
    public function cardReceive(array $params)
    {
        $userInfo = auth()->user();
        $cardInfo = $this->usersCardsInfoDao->getCardInfoBy($userInfo->getId(),$params['to_uid'],$params['card_id']);

        if($cardInfo) throw new ServiceException("您已领取过该卡，无需继续领取");

        $merchantCardInfo = $this->usersCardDao->getCardById($params['card_id']);

        if(!$merchantCardInfo) throw new ServiceException("卡不存在");

        $merchantUserInfo = User::query()->where('id','=',$params['to_uid'])->first();

        if(!$merchantUserInfo) throw new ServiceException("发卡实体不存在");

        $disAmount = AmountUtils::yuanTofen($params['amount']);
        $userCardData = [
            'uid' => $userInfo->getId(),
            'card_id' => $merchantCardInfo->id,
            'to_uid' => $params['to_uid'],
            'card_type' => UserCardInfoTypeConst::CUSTOM_GET->value,
            'user_name' => $params['user_name'],
            'card_cids' => $merchantCardInfo->card_cids,
            'card_no' => UsersCardsInfo::getCardNo(),
            'card_color' => $merchantCardInfo->card_color,
            'card_name' => $merchantCardInfo->card_name,
            'card_desc' => $merchantCardInfo->card_desc,
            'company_name' => $merchantUserInfo->company_name,
            'card_discount' => $merchantCardInfo->card_discount,
            'status' => SysStatusConst::NORMAL->value,
            'amount' => $disAmount,
        ];
        $cardUserAccountInfo = $this->usersAccountDao->getSysAccountInfo($userInfo->getId());
        /**
         * 客户账户动账
         */
        $cardUserAccountInfo->in_amount = bcadd($cardUserAccountInfo->in_amount,$disAmount);
        $cardUserAccountInfo->amount = bcadd($cardUserAccountInfo->amount,$disAmount);
        $cardUserAccountInfo->save();

        $userCardInfo = $this->usersCardsInfoDao->add(new UsersCardsInfo(),$userCardData);

        return $userCardInfo->toArray();
    }


    public function userCardQrcode(int $cardId)
    {
        $userInfo = auth()->user();

        $userCardInfo = $this->usersCardsInfoDao->getCardInfoById($userInfo->getId(),$cardId);
        $time = time();
        if(!$userCardInfo) throw new ServiceException("会员卡不存在");
        return (new QrCodeService())->createQrCode($userCardInfo->card_no.'#'.$time);
    }






}